<script lang="ts" setup>
import { ref, reactive, toRefs, watch, computed } from 'vue';
import { Page } from '@vben/common-ui';
import { ElMessageBox, ElMessage } from "element-plus";
import { trimStringParams } from '#/utils/trimStringParams';
import { OrgTree, Query } from './modules/certificatesMgr';
import { getCertificatePageApi, updateCertificateStatusApi, createCertificateApi } from '#/api/certificate/certificatesMgr';
import { statusBg, statusData } from './modules/certificatesMgr/const';
import { RotateCw, Send, Ban, Eye, Loader } from '@vben/icons';
import certFail from "#/assets/images/certificate/cert-fail.png"
import { $t } from '@vben/locales';
import { PdfThumbnail } from './modules/certificatesMgr';
import ResizableLayout from '#/components/common/resizable-layout.vue'

const defaultQueryData = {
  nameCn: '',
  status: null,
};
const queryData = reactive({ ...defaultQueryData });
const tableLoading = reactive([0, 0]);
const loading = ref(false);
const certifiedId = ref(null);
const orgId = ref(null);
const selectAll = ref(false);
const pdfThumbnailRefs = ref<Record<string, any>>({})
const certificates = ref([])

const total = ref(0)
const pageData = reactive({
  curPage: 1,
  pageSize: 10,
});

function statusText(status: string) {
  switch (status) {
    case 'unpublished': return $t('certificatesMgr.unpublishedTxt')
    case 'waiting': return $t('certificatesMgr.waitingTxt')
    case 'processing': return $t('certificatesMgr.processingTxt')
    case 'success': return $t('certificatesMgr.successTxt')
    case 'failed': return $t('certificatesMgr.failedTxt')
    case 'published': return $t('certificatesMgr.publishedTxt')
    case 'disabled': return $t('certificatesMgr.isDeletedTxt')
    default: return ''
  }
}
const handleSizeChange = (val: number) => {
  pageData.pageSize = val
  pageData.curPage = 1
  getTabelData()
}
const handleCurrentChange = (val: number) => {
  pageData.curPage = val
  getTabelData()
}

const getTabelData = () => {
  if (!certifiedId.value || !orgId.value) {
    ElMessage.warning($t('certificatesMgr.noDataTxt'))
    return
  }
  const { curPage, pageSize } = toRefs(pageData)
  const params = {
    certificationId: certifiedId.value,
    orgId: orgId.value,
    curPage: curPage.value,
    pageSize: pageSize.value
  } as any;
  selectAll.value = false
  const trimData = trimStringParams(queryData.nameCn)
  if (trimData) {
    params.nameCn = trimData
  }
  if (queryData.status !== null) {
    const queryType = statusData.find((item: any) => item.name === queryData.status)
    if (queryType?.key) {
      params[queryType.key] = queryType.value
    }
  }
  tableLoading[0] = 1
  getCertificatePageApi(params)
    .then((res) => {
      const { data, pageInfo } = res;
      const list = data.map((item: any) => {
        return {
          ...item,
          selected: false,
          status: item.isDeleted ? 'disabled' : (item.taskStatus === 'SUCCESS' ? (item.publishStatus === 1 ? 'published' : 'unpublished') : item.taskStatus.toLowerCase())
        }
      })
      console.log(list);
      certificates.value = list;
      total.value = pageInfo?.totalRows
    })
    .finally(() => {
      tableLoading[0] = 0;
    });
}

const resetQuery = () => {
  Object.assign(queryData, defaultQueryData)
  getTabelData()
}

const queryCert = (params: any) => {
  certifiedId.value = params.certifiedId
  orgId.value = params.id
  getTabelData()
}

const recreate = (item: any) => {
  const params = {
    userIds: Array.isArray(item.userId) ? item.userId : [item.userId],
    certificationId: certifiedId.value,
    orgId: orgId.value,
  } as any;
  item.loading = true
  createCertificateApi(params).then((res) => {
    item.status = 'processing'
    console.log(res)
  }).finally(() => {
    item.loading = false
  })
}
const preview = (item: any) => {
  const componentRef = pdfThumbnailRefs.value[item.id]
  console.log(componentRef)
  console.log(item)
  if (componentRef) {
    componentRef.handlePreview()
  }
}

const publish = (item: any) => {
  ElMessageBox.confirm(
    $t('certificatesMgr.publishTxt'),
    $t('common.tipTxt'),
    {
      confirmButtonText: $t('common.submitTxt'),
      cancelButtonText: $t('common.cancelTxt'),
      type: 'warning',
    }
  )
    .then(() => {
      const params = {
        ids: Array.isArray(item.id) ? item.id : [item.id],
        certificationId: certifiedId.value,
        orgId: orgId.value,
        isPublish: 1
      } as any;
      item.loading = true
      updateCertificateStatusApi(params).then(() => {
        getTabelData()
      }).finally(() => {
        item.loading = false
      })
    })
    .catch(() => { })
}
const banDisabled = (item: any) => {
  ElMessageBox.confirm(
    $t('certificatesMgr.banTxt'),
    $t('common.tipTxt'),
    {
      confirmButtonText: $t('common.submitTxt'),
      cancelButtonText: $t('common.cancelTxt'),
      type: 'warning',
    }
  )
    .then(() => {
      console.log(item)
      const params = {
        ids: Array.isArray(item.id) ? item.id : [item.id],
        certificationId: certifiedId.value,
        orgId: orgId.value,
        isDeleted: 1
      } as any;
      item.loading = true
      updateCertificateStatusApi(params).then(() => {
        getTabelData()
      }).finally(() => {
        item.loading = false
      })
    })
    .catch(() => { })

}

const createCertificate = () => {
  if (certificates.value.length === 0) {
    ElMessage.warning($t('certificatesMgr.noRelatedUserTxt'))
    return
  }
  const userIds = certificates.value.filter((item: any) => item.selected).map((item: any) => item.userId)
  if (userIds.length === 0) {
    ElMessage.warning($t('common.selectPhTxt', [$t('certificatesMgr.failedCertificatesTxt')]))
    return
  }
  const params = {
    certificationId: certifiedId.value,
    orgId: orgId.value,
    userIds: certificates.value.length > 0 ? userIds : null,
  } as any;
  createCertificateApi(params).then(() => {
    getTabelData()
  })
}
const loadSuccess = (item: any, val: any) => {
  item.certificateImgLoaded = val
}

const handleSelectAll = (val: any) => {
  selectAll.value = val
  certificates.value.forEach((item: any) => {
    if (item.status === 'unpublished' || item.status === 'failed') {
      item.selected = val
    }
  })
}

const handleSelect = () => {
  const checkboxList = certificates.value.filter((item: any) => (item.status === 'unpublished') || (item.status === 'failed')) || []
  const selectList = checkboxList.filter((item: any) => item.selected) || []
  selectAll.value = selectList.length === checkboxList.length
}

const handlePush = () => {
  if (certificates.value.length === 0) {
    ElMessage.warning($t('certificatesMgr.noRelatedUserTxt'))
    return
  }
  const ids = certificates.value.filter((item: any) => item.selected).map((item: any) => item.id)
  if (ids.length === 0) {
    ElMessage.warning($t('common.selectPhTxt', [$t('certificatesMgr.unpublishedCertificatesTxt')]))
    return
  }
  const params = {
    ids,
    certificationId: certifiedId.value,
    orgId: orgId.value,
    isPublish: 1
  } as any;
  updateCertificateStatusApi(params).then(() => {
    getTabelData()
  }).finally(() => {
  })
}

watch(
  () => tableLoading,
  (val) => {
    if (val) {
      const isLoading = val.some(i => i === 1)
      loading.value = isLoading
    }
  },
  { deep: true },
)

const getSelectAll = computed(() => {
  const checkboxList = certificates.value.filter((item: any) => (item.status === 'unpublished') || (item.status === 'failed')) || []
  const selectList = checkboxList.filter((item: any) => item.selected) || []
  return selectList.length < checkboxList.length && selectList.length > 0
})

const handleResize = (width: number) => {
  console.log('左侧面板宽度调整为:', width)
}

</script>
<template>
  <Page class="h-full">
    <section class="flex h-full bg-[#fff] rounded-sm">
      <ResizableLayout 
        :default-width="200"
        :min-width="200"
        :max-width="500"
        :handle-width="1"
        :handle-color="'#DCDFE6'"
        @resize="handleResize"
      >
      <!-- 左侧菜单 -->
       <template #left>
        <aside class="w-full h-full p-[24px] pr-4">
          <OrgTree @queryCert="queryCert"></OrgTree>
        </aside>
      </template>
      <template #right>
      <!-- 右侧内容区 -->
        <main v-loading="loading" class="flex-1 h-full p-6">
          <div class="w-full h-full flex flex-col">
            <!-- 搜索栏 -->
            <Query v-model="queryData" class="mb-[5px]" @query-data="getTabelData" @reset-query="resetQuery"></Query>
            <!-- 操作按钮区 -->
            <div class=" mb-4 space-x-4">
              <el-button type="primary" @click="createCertificate">{{ certificates.length > 0 ?
                $t('certificatesMgr.reNewTxt') : $t('certificatesMgr.createTxt') }}</el-button>
              <el-button @click="handlePush">{{ $t('common.pushTxt') }}</el-button>
              <el-checkbox v-if="certificates.length > 0" class="float-right" :indeterminate="getSelectAll"
                v-model="selectAll" @change="handleSelectAll">{{ $t('common.selectAllTxt') }}</el-checkbox>
            </div>

            <!-- 证书卡片区 -->
            <div class="flex-1 overflow-scroll">
              <div v-if="certificates.length > 0" class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 2xl:grid-cols-6 gap-4 mb-6">
                <template v-for="item in certificates as any" :key="item.id">
                  <!-- 证书卡片 -->
                  <div v-loading="item.loading"
                    class="certifi-card flex flex-col min-w-[140px] overflow-hidden relative cursor-pointer bg-[#F2F7FD] border border-[#ebeef5] rounded-lg min-h-[200px]  hover:shadow-lg transition-shadow">
                    <!-- 状态角标 -->
                    <div class="flex items-center justify-between pt-[6px] pl-[12px] pr-[12px] pb-[3px] space-x-1">
                      <span class="text-xs text-[#191919] font-[500] whitespace-nowrap overflow-hidden text-ellipsis">
                        {{ item.nameCn }}
                      </span>
                      <div class="flex items-center flex-shrink-0">
                        <span class="w-2 h-2 rounded-full bg-[#30A46C]"
                          :class="[`bg-[${statusBg[item.status as keyof typeof statusBg]}]`]"></span>
                        <span class="text-xs text-[#595959] ml-[5px]">
                          {{ statusText(item.status) }}
                        </span>
                        <el-checkbox @change="handleSelect()"
                          v-if="item.status === 'failed' || item.status === 'unpublished'"
                          class="selected-certifi ml-[8px]" v-model="item.selected" label="" />
                      </div>
                    </div>
                    <div class="text-[#595959] text-xs pl-[12px] pb-[8px]">{{ item.phone || '--' }}</div>
                    <!-- 生成中卡片 -->
                    <div v-if="item.taskStatus === 'WAITING' || item.taskStatus === 'PROCESSING'"
                      class="flex flex-col items-center justify-center flex-1 bg-[#19191933] relative">
                      <div class="text-[#909399] text-sm mb-1">
                        <Loader class="circular"></Loader>
                      </div>
                    </div>
                    <!-- 生成失败卡片 -->
                    <div v-if="item.taskStatus === 'FAILED'"
                      class="flex flex-col items-center justify-center flex-1 bg-[#19191933] relative">
                      <img :src="certFail" class="w-16 h-16 mb-2" />
                      <div class="text-[#909399] text-[14px] mb-1">{{ $t('common.certificateTxt',
                        [$t('certificatesMgr.failedTxt')]) }}</div>
                      <div @click="recreate(item)"
                        class="w-full h-[32px] absolute bottom-0 left-0 leading-[30px] bg-[#000000cc] hover:bg-[#00000099] text-[#fff] text-[12px] text-center">
                        <el-tooltip effect="dark" :content="$t('certificatesMgr.reNewTxt')" :show-after="1000" placement="top">
                          <RotateCw class="inline-block w-[16px] h-[16px]" />
                        </el-tooltip>
                      </div>
                    </div>
                    <!-- 证书图片 -->
                    <div v-if="item.taskStatus === 'SUCCESS'" class="w-full flex-1 bg-[#19191933]">
                      <PdfThumbnail :ref="(el) => { if (el) pdfThumbnailRefs[item.id] = el }"
                        :certificate="item.certificate" @loadSuccess="(val) => loadSuccess(item, val)" />
                    </div>
                    <div v-if="item.taskStatus === 'SUCCESS'"
                      class="card-handler absolute w-full h-[32px] bottom-[-32px] opacity-[0] left-0 flex items-center cursor-pointer">
                      <div
                        class="flex-1 h-full leading-[30px] border-r border-[#DCDFE6] bg-[#000000cc] hover:bg-[#00000099] text-[#fff] text-center">
                        <el-tooltip v-if="item.status === 'disabled' || item.status === 'unpublished'" effect="dark" :content="$t('common.pushTxt')" :show-after="1000" placement="top">
                          <Send @click="publish(item)"
                          class="inline-block w-[16px] h-[16px]"></Send>
                        </el-tooltip>
                        <el-tooltip v-else effect="dark" :content="$t('common.stopTxt')" :show-after="1000" placement="top">
                          <Ban @click="banDisabled(item)" class="inline-block w-[16px] h-[16px]"></Ban>
                        </el-tooltip>
                      </div>
                      <div @click="preview(item)" v-if="item.status !== 'failed'"
                        class="flex-1 h-full leading-[30px] bg-[#000000cc] hover:bg-[#00000099] text-[#fff] text-center">
                        <el-tooltip effect="dark" :content="$t('common.previewTxt')" :show-after="1000" placement="top">
                          <Eye class="inline-block w-[16px] h-[16px]"></Eye>
                        </el-tooltip>
                      </div>
                    </div>
                  </div>
                </template>
              </div>
              <div v-else class="flex items-center justify-center h-full">
                <div v-if="!loading" class="text-[#909399] text-sm">{{ $t('common.emptyTxt') }}</div>
              </div>
            </div>
            <!-- 分页 -->
            <div class="flex items-center justify-between">
              <ElPagination @size-change="handleSizeChange" @current-change="handleCurrentChange"
                class="pagination pt-[15px]" size="small" layout="total, sizes, prev, pager, next, jumper"
                :page-sizes="[10, 20, 50, 100]" :page-size="pageData.pageSize" :total="total"></ElPagination>
            </div>
            </div>
          </main>
        </template>
      </ResizableLayout>
    </section>
  </Page>
</template>
<style scoped lang="scss">
:deep(.selected-certifi .el-checkbox__label) {
  padding: 0px;
}

:deep(.selected-certifi.el-checkbox) {
  height: 14px;
}

.circular {
  width: 18px;
  height: 18px;
  animation: loading-rotate 2s linear infinite;
}

.certifi-card {
  &:hover {
    .card-handler {
      bottom: 0px;
      opacity: 1;
      transition: all .3s ease-in;
    }
  }
}
</style>
